package com.kexio.core.security.util;

import com.kexio.core.security.context.UserContext;
import com.kexio.core.security.context.UserContextHolder;
import java.util.List;

/**
 * 用户信息工具类
 * 提供便捷的用户信息获取方法
 *
 * @author Kexio Team
 * @since 1.0.0
 */
public class UserInfoUtils {

    /**
     * 获取当前用户ID
     *
     * @return 用户ID
     */
    public static Long getCurrentUserId() {
        return UserContextHolder.getCurrentUserId();
    }

    /**
     * 获取当前用户名
     *
     * @return 用户名
     */
    public static String getCurrentUsername() {
        return UserContextHolder.getCurrentUsername();
    }

    /**
     * 获取当前用户昵称
     *
     * @return 用户昵称
     */
    public static String getCurrentNickname() {
        return UserContextHolder.getCurrentNickname();
    }

    /**
     * 获取当前用户完整上下文
     *
     * @return 用户上下文
     */
    public static UserContext getCurrentUser() {
        return UserContextHolder.getContext();
    }

    /**
     * 获取当前租户ID
     *
     * @return 租户ID
     */
    public static Long getCurrentTenantId() {
        return UserContextHolder.getCurrentTenantId();
    }

    /**
     * 获取当前部门ID
     *
     * @return 部门ID
     */
    public static Long getCurrentDeptId() {
        return UserContextHolder.getCurrentDeptId();
    }

    /**
     * 获取当前用户邮箱
     *
     * @return 邮箱
     */
    public static String getCurrentUserEmail() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getEmail() : null;
    }

    /**
     * 获取当前用户手机号
     *
     * @return 手机号
     */
    public static String getCurrentUserPhone() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getPhone() : null;
    }

    /**
     * 获取当前用户头像
     *
     * @return 头像地址
     */
    public static String getCurrentUserAvatar() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getAvatar() : null;
    }

    /**
     * 获取当前租户名称
     *
     * @return 租户名称
     */
    public static String getCurrentTenantName() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getTenantName() : null;
    }

    /**
     * 获取当前部门名称
     *
     * @return 部门名称
     */
    public static String getCurrentDeptName() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getDeptName() : null;
    }

    /**
     * 获取当前用户角色列表
     *
     * @return 角色列表
     */
    public static List<String> getCurrentUserRoles() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getRoles() : null;
    }

    /**
     * 获取当前用户权限列表
     *
     * @return 权限列表
     */
    public static List<String> getCurrentUserPermissions() {
        UserContext context = UserContextHolder.getContext();
        return context != null ? context.getPermissions() : null;
    }

    /**
     * 检查当前用户是否拥有指定角色
     *
     * @param role 角色标识
     * @return 是否拥有该角色
     */
    public static boolean hasRole(String role) {
        return UserContextHolder.hasRole(role);
    }

    /**
     * 检查当前用户是否拥有任意指定角色
     *
     * @param roles 角色标识数组
     * @return 是否拥有任意一个角色
     */
    public static boolean hasAnyRole(String... roles) {
        return UserContextHolder.hasAnyRole(roles);
    }

    /**
     * 检查当前用户是否拥有指定权限
     *
     * @param permission 权限标识
     * @return 是否拥有该权限
     */
    public static boolean hasPermission(String permission) {
        return UserContextHolder.hasPermission(permission);
    }

    /**
     * 检查当前用户是否拥有任意指定权限
     *
     * @param permissions 权限标识数组
     * @return 是否拥有任意一个权限
     */
    public static boolean hasAnyPermission(String... permissions) {
        return UserContextHolder.hasAnyPermission(permissions);
    }

    /**
     * 检查当前用户是否拥有全部指定权限
     *
     * @param permissions 权限标识数组
     * @return 是否拥有全部权限
     */
    public static boolean hasAllPermissions(String... permissions) {
        return UserContextHolder.hasAllPermissions(permissions);
    }

    /**
     * 检查当前用户是否为超级管理员
     *
     * @return 是否为超级管理员
     */
    public static boolean isAdmin() {
        return UserContextHolder.isAdmin();
    }

    /**
     * 检查是否存在当前用户上下文
     *
     * @return 是否存在用户上下文
     */
    public static boolean hasCurrentUser() {
        return UserContextHolder.hasContext();
    }

    /**
     * 检查当前用户是否为指定用户
     *
     * @param userId 用户ID
     * @return 是否为指定用户
     */
    public static boolean isCurrentUser(Long userId) {
        Long currentUserId = getCurrentUserId();
        return currentUserId != null && currentUserId.equals(userId);
    }

    /**
     * 检查当前用户是否为指定用户
     *
     * @param username 用户名
     * @return 是否为指定用户
     */
    public static boolean isCurrentUser(String username) {
        String currentUsername = getCurrentUsername();
        return currentUsername != null && currentUsername.equals(username);
    }

    /**
     * 检查当前用户是否属于指定租户
     *
     * @param tenantId 租户ID
     * @return 是否属于指定租户
     */
    public static boolean isCurrentTenant(Long tenantId) {
        Long currentTenantId = getCurrentTenantId();
        return currentTenantId != null && currentTenantId.equals(tenantId);
    }

    /**
     * 检查当前用户是否属于指定部门
     *
     * @param deptId 部门ID
     * @return 是否属于指定部门
     */
    public static boolean isCurrentDept(Long deptId) {
        Long currentDeptId = getCurrentDeptId();
        return currentDeptId != null && currentDeptId.equals(deptId);
    }

    /**
     * 设置当前用户上下文
     * 注意: 此方法应谨慎使用，通常由安全框架调用
     *
     * @param userContext 用户上下文
     */
    public static void setCurrentUser(UserContext userContext) {
        UserContextHolder.setContext(userContext);
    }

    /**
     * 设置当前租户ID
     * 注意: 此方法主要用于多租户场景下的租户切换
     *
     * @param tenantId 租户ID
     */
    public static void setCurrentTenantId(Long tenantId) {
        UserContext context = UserContextHolder.getContext();
        if (context != null) {
            context.setTenantId(tenantId);
            UserContextHolder.setContext(context);
        }
    }

    /**
     * 清除当前用户上下文
     * 注意: 此方法应谨慎使用，通常由安全框架调用
     */
    public static void clearCurrentUser() {
        UserContextHolder.clear();
    }

    /**
     * 创建当前用户上下文的快照
     *
     * @return 用户上下文快照
     */
    public static UserContext createCurrentUserSnapshot() {
        return UserContextHolder.createSnapshot();
    }

    /**
     * 以指定用户身份执行任务
     *
     * @param userContext 用户上下文
     * @param task        任务
     * @param <T>         返回值类型
     * @return 任务执行结果
     */
    public static <T> T runAsUser(UserContext userContext, java.util.function.Supplier<T> task) {
        return UserContextHolder.runAs(userContext, task);
    }

    /**
     * 以指定用户身份执行任务(无返回值)
     *
     * @param userContext 用户上下文
     * @param task        任务
     */
    public static void runAsUser(UserContext userContext, Runnable task) {
        UserContextHolder.runAs(userContext, task);
    }

    /**
     * 以超级管理员身份执行任务
     *
     * @param task 任务
     * @param <T>  返回值类型
     * @return 任务执行结果
     */
    public static <T> T runAsAdmin(java.util.function.Supplier<T> task) {
        UserContext adminContext = UserContext.builder()
                .userId(0L)
                .username("system")
                .nickname("系统管理员")
                .tenantId(1L)
                .isAdmin(true)
                .build();
        return runAsUser(adminContext, task);
    }

    /**
     * 以超级管理员身份执行任务(无返回值)
     *
     * @param task 任务
     */
    public static void runAsAdmin(Runnable task) {
        runAsAdmin(() -> {
            task.run();
            return null;
        });
    }

    /**
     * 以系统身份执行任务(无用户上下文)
     *
     * @param task 任务
     * @param <T>  返回值类型
     * @return 任务执行结果
     */
    public static <T> T runAsSystem(java.util.function.Supplier<T> task) {
        return runAsUser(null, task);
    }

    /**
     * 以系统身份执行任务(无用户上下文，无返回值)
     *
     * @param task 任务
     */
    public static void runAsSystem(Runnable task) {
        runAsSystem(() -> {
            task.run();
            return null;
        });
    }
}
